package com.longlonggo.shiro.realm;

import com.longlonggo.entity.RoleEntity;
import com.longlonggo.entity.RolePermissionEntity;
import com.longlonggo.entity.UserEntity;
import com.longlonggo.service.RolePermissionService;
import com.longlonggo.service.RoleService;
import com.longlonggo.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * 验证及获取登录权限信息<br/>
 *
 * @author 石马人山 me@longlonggo.com
 * @version 100-000-000<br/>
 * @Created 2018年4月25日 下午7:54:53
 * </p>
 * @description <br/>
 */
// 参考shiro配置https://www.cnblogs.com/hlhdidi/p/6376457.html
public class UserRealm extends AuthorizingRealm {

    @Resource
    private UserService userService;
    @Resource
    private RoleService roleService;
    @Resource
    private RolePermissionService rolePermissionService;


    //授权
    // 用于获取认证成功后的角色、权限等信息
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
//		String currentLoginName = (String) principals.getPrimaryPrincipal();//获取存入session的用户
        UserEntity user = (UserEntity) principals.getPrimaryPrincipal();//获取存入session的用户
        List<String> userRoleList = new ArrayList<String>();
        List<String> userPermissionList = new ArrayList<String>();

        // 从数据库中获取当前登录用户的详细信息
//		UserEntity user = userService.queryByUserName(currentLoginName);
        if (null != user) {
            // 获取当前用户下拥有的所有角色列表,和权限
            List<RoleEntity> roleList = roleService.queryListByUserId(user.getUserId());
            for (RoleEntity roleEntity : roleList) {
                userRoleList.add(roleEntity.getRoleId().toString());
                //@ TODO改地方需要改成获取权限集合，从数据库取值
//				userPermissionList.add(roleEntity.get)

                //将每个角色关联的权限记录到权限表中
                List<RolePermissionEntity> RolePermissionList = rolePermissionService.queryListByRoleId(roleEntity.getRoleId());
                for (RolePermissionEntity rolePermissionEntity : RolePermissionList) {
                    userPermissionList.add(rolePermissionEntity.getRpPermissionId().toString());
                }
            }

        } else {
            throw new AuthorizationException();
        }
        System.out.println("#######获取角色：" + userRoleList);
        System.out.println("#######获取权限：" + userPermissionList);

        // 为当前用户设置角色和权限
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        authorizationInfo.addRoles(userRoleList);
        authorizationInfo.addStringPermissions(userPermissionList);
        return authorizationInfo;
    }


    //认证登录
    //LoginController.login()方法中执行Subject.login()时 执行此方法
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken)
            throws AuthenticationException {
        System.out.println("###【开始认证[SessionId]】" + SecurityUtils.getSubject().getSession().getId());
        String loginName = (String) authcToken.getPrincipal();
        UserEntity user = userService.queryByUserName(loginName);
        if (user == null) {
            throw new UnknownAccountException();// 没找到帐号
        }

        // 交给AuthenticatingRealm使用CredentialsMatcher进行密码匹配，如果觉得人家的不好可以自定义实现
        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user, // 将用户放入shiro的session中
                user.getUserPassword(), // 密码
//				ByteSource.Util.bytes(user.getCredentialsSalt()), // salt=username+salt,采用明文访问时，不需要此句
                getName() // realm name
        );
        return authenticationInfo;
    }

    public static void main(String[] args) {
        System.out.println(ByteSource.Util.bytes("123456"));
    }

}
